package com.zoffy.wmsbackend.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zoffy.wmsbackend.common.BaseResponse;
import com.zoffy.wmsbackend.common.ResultUtils;
import com.zoffy.wmsbackend.mapper.*;
import com.zoffy.wmsbackend.mapper.report.ReportSummaryDayStockInMapper;
import com.zoffy.wmsbackend.model.entity.*;
import com.zoffy.wmsbackend.model.vo.report.SummaryDayStockIn;
import com.zoffy.wmsbackend.model.vo.report.SummaryDayStockInData;
import com.zoffy.wmsbackend.model.vo.report.SummaryDayStockOut;
import com.zoffy.wmsbackend.model.vo.report.SummaryDayStockOutData;
import com.zoffy.wmsbackend.service.GoodsService;
import com.zoffy.wmsbackend.service.ReportService;
import com.zoffy.wmsbackend.service.report.ReportDaySummaryStockInService;
import com.zoffy.wmsbackend.service.report.ReportDaySummaryStockOutService;
import jakarta.annotation.Resource;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@PreAuthorize("hasAuthority('admin')")
@RequestMapping("/report")
public class ReportController {
    @Resource
    private ReportService reportService;
    @Resource
    private WarehouseMapper warehouseMapper;
    @Resource
    private ReportDaySummaryStockInService reportDaySummaryStockInService;
    @Resource
    private ReportDaySummaryStockOutService reportDaySummaryStockOutService;
    @Resource
    private StockInOrderMapper stockInOrderMapper;
    @Resource
    private StockOutOrderMapper stockOutOrderMapper;
    @Resource
    private GoodsService goodsService;
    @Resource
    private StockInOrderDetailMapper stockInOrderDetailMapper;
    @Resource
    private StockOutOrderDetailMapper stockOutOrderDetailMapper;

    @GetMapping("/summary/day/stock-in")
    public BaseResponse<List<SummaryDayStockIn>> getReportDaySummaryStockIn(String endDate, Integer deltaTime) {
        List<SummaryDayStockIn> res = reportService.getSummaryDayStockIn(endDate, deltaTime);
        return ResultUtils.success(res);
    }
    @GetMapping("/summary/day/stock-in-data")
    public BaseResponse<SummaryDayStockInData> getReportDaySummaryStockInData(String endDate) {
        SummaryDayStockInData res = reportService.getSummaryDayStockInSum(endDate);
        return ResultUtils.success(res);
    }

    @GetMapping("/summary/day/stock-out")
    public BaseResponse<List<SummaryDayStockOut>> getReportDaySummaryStockIOut(String endDate, Integer deltaTime) {
        List<SummaryDayStockOut> res = reportService.getSummaryDayStockOut(endDate, deltaTime);
        return ResultUtils.success(res);
    }
    @GetMapping("/summary/day/stock-out-data")
    public BaseResponse<SummaryDayStockOutData> getReportDaySummaryStockOutData(String endDate) {
        SummaryDayStockOutData res = reportService.getSummaryDayStockOutSum(endDate);
        return ResultUtils.success(res);
    }

    @Scheduled(cron = "0 0 1 * * *")
    public void calculateReportDaySummaryStockIn(){
        Map<Long, Integer> goodsMap = goodsService.list(new QueryWrapper<Goods>()).stream().collect(Collectors.toMap(Goods::getId, Goods::getAmountGd));
        Date enddate = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = sdf.getCalendar();
        calendar.setTime(enddate);
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        String startTime = sdf.format(calendar.getTime());
        String endTime = sdf.format(enddate);
        QueryWrapper<Warehouse> wrapper = new QueryWrapper<Warehouse>();
        List<ReportDaySummaryStockIn> reportDaySummaryStockInList=new ArrayList<>();
        warehouseMapper.selectList(wrapper).forEach(warehouse -> {
            QueryWrapper<StockInOrderDetail> stockInDetailWrapper = new QueryWrapper<>();
            stockInDetailWrapper.eq("warehouse_id", warehouse.getId());
            stockInDetailWrapper.ge("create_time", startTime);
            stockInDetailWrapper.le("create_time", endTime);
            List<StockInOrderDetail> details = stockInOrderDetailMapper.selectList(stockInDetailWrapper);
            Long goodsAmountGd= 0L;
            Long goodsNum = 0L;
            Integer orderNum = 0;
            for (StockInOrderDetail detail : details) {
                goodsNum+=detail.getQuantity();
                goodsAmountGd+= (long) detail.getQuantity() *goodsMap.get(detail.getGoodsId());
            }
            QueryWrapper<StockInOrder> stockInWrapper = new QueryWrapper<>();
            stockInWrapper.eq("warehouse_id", warehouse.getId());
            stockInWrapper.ge("create_time", startTime);
            stockInWrapper.le("create_time", endTime);
            List<StockInOrder> order = stockInOrderMapper.selectList(stockInWrapper);
            orderNum = order.size();
            ReportDaySummaryStockIn data = new ReportDaySummaryStockIn();
            data.setWarehouseId(warehouse.getId());
            data.setTime(startTime.toString());
            data.setOrderNum(orderNum);
            data.setGoodsNum(goodsNum);
            data.setGoodsAmountGd(String.valueOf(goodsAmountGd));
            reportDaySummaryStockInList.add(data);
        });
        reportDaySummaryStockInService.saveBatch(reportDaySummaryStockInList);
    }

    @Scheduled(cron = "0 0 1 * * *")
    public void calculateReportDaySummaryStockOut(){
        Map<Long, Integer> goodsMap = goodsService.list(new QueryWrapper<Goods>()).stream().collect(Collectors.toMap(Goods::getId, Goods::getAmountGd));
        Date endDate = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = sdf.getCalendar();
        calendar.setTime(endDate);
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        String startTime = sdf.format(calendar.getTime());
        String endTime = sdf.format(endDate);
        QueryWrapper<Warehouse> wrapper = new QueryWrapper<>();
        List<ReportDaySummaryStockOut> reportDaySummaryStockOutList=new ArrayList<>();
        warehouseMapper.selectList(wrapper).forEach(warehouse -> {
            QueryWrapper<StockOutOrderDetail> stockOutDetailWrapper = new QueryWrapper<>();
            stockOutDetailWrapper.eq("warehouse_id", warehouse.getId());
            stockOutDetailWrapper.ge("create_time", startTime);
            stockOutDetailWrapper.lt("create_time", endTime);
            List<StockOutOrderDetail> details = stockOutOrderDetailMapper.selectList(stockOutDetailWrapper);
            Long goodsAmountGd= 0L;
            Long goodsNum = 0L;
            Integer orderNum = 0;
            for (StockOutOrderDetail detail : details) {
                goodsNum+=detail.getQuantity();
                goodsAmountGd+= (long) detail.getQuantity() *goodsMap.get(detail.getGoodsId());
            }
            QueryWrapper<StockOutOrder> stockOutWrapper = new QueryWrapper<>();
            stockOutWrapper.eq("warehouse_id", warehouse.getId());
            stockOutWrapper.ge("create_time", startTime);
            stockOutWrapper.le("create_time", endTime);
            List<StockOutOrder> order = stockOutOrderMapper.selectList(stockOutWrapper);
            orderNum = order.size();
            ReportDaySummaryStockOut data = new ReportDaySummaryStockOut();
            data.setWarehouseId(warehouse.getId());
            data.setTime(startTime.toString());
            data.setOrderNum(orderNum);
            data.setGoodsNum(goodsNum);
            data.setGoodsAmountGd(String.valueOf(goodsAmountGd));
            reportDaySummaryStockOutList.add(data);
        });
        reportDaySummaryStockOutService.saveBatch(reportDaySummaryStockOutList);
    }
}
